package com.ouc.eddyAlgorithm.service.impl;


import com.ouc.common.utils.ArrayUtils;
import com.ouc.eddyAlgorithm.dao.VGDao;
import com.ouc.eddyAlgorithm.domain.VgEddy;
import com.ouc.eddyAlgorithm.entity.VGGridData;
import com.ouc.eddyAlgorithm.service.VGService;
import com.ouc.visualization.entity.ContourData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ucar.ma2.InvalidRangeException;
import ucar.nc2.NetcdfFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

@Service
public class VGServiceImpl implements VGService {

  @Autowired
  private VGDao vgDao;


  @Override
  public ContourData<VGGridData> getVGContourData(String fileName, int a, int b, int level, boolean[] constraints, Float[] lon, Float[] lat) throws IOException, InvalidRangeException {
    NetcdfFile file = NetcdfFile.open(fileName);
    VGGridData vgGridData = vgDao.getVGGridData(file, a, b, level, constraints, lon, lat);
    ContourData<VGGridData> contourData = new ContourData<>();
    if (vgGridData == null) {
      return contourData;
    }

    float[] listLon = vgGridData.getListLon();
    int lonLength = listLon.length;
    float lonInterval = BigDecimal.valueOf(listLon[1]).subtract(BigDecimal.valueOf(listLon[0])).setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();//四舍五入保留两位小数
    float startLon = listLon[0];
    float[] listLat = vgGridData.getListLat();
    int latLength = listLat.length;
    float latInterval = BigDecimal.valueOf(listLat[1]).subtract(BigDecimal.valueOf(listLat[0])).setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();//四舍五入保留两位小数
    float startLat = listLat[0];
    contourData = new ContourData<>(vgGridData, -1, 2,
        lonLength, latLength, lonInterval, latInterval, startLon, startLat, vgGridData.getVariableName());
    return contourData;
  }

  @Override
  public float[][] getSurfaceData(String fileName, String variableName, Integer level) throws IOException, InvalidRangeException {
    float[][] res = null;
    switch (variableName) {
      case "temp":
      case "salt":
        res = vgDao.getSurfaceData(NetcdfFile.open(fileName), variableName, level);
        break;
      case "flow":
        float[][] uus = vgDao.getSurfaceData(NetcdfFile.open(fileName), "uu", level);
        float[][] vvs = vgDao.getSurfaceData(NetcdfFile.open(fileName), "vv", level);
        res = new float[uus.length][uus[0].length];
        for (int i = 0; i < uus.length; i++) {
          for (int j = 0; j < uus[0].length; j++) {
            res[i][j] = (float) Math.sqrt(Math.pow(uus[i][j], 2) + Math.pow(vvs[i][j], 2));
          }
        }
        break;
    }
    return ArrayUtils.transpose(res);
  }

  @Override
  public List<VgEddy> getVgEddyMatrixOfSlice(NetcdfFile ncFile, Integer a, Integer b, boolean[] constraints, Float[] lonLimit, Float[] latLimit, Integer level, Integer eddyStartId) throws IOException, InvalidRangeException {
    return vgDao.getVgEddyMatrixWithLimitLevel(ncFile, a, b, constraints, lonLimit, latLimit, new Integer[]{level, level}, eddyStartId).get(0);
  }
}
